let member_no = '' // 会员编号
let member_level_no = '' // 会员等级编号

/**
 * @description 计算账单数据
 * @property {array} cartList -购物车列表 amount-加购数量 
 * @property {object} vipInfo -会员信息 member_level_no,menber_no
 * @property {object} discountData -折扣数据
 * @property {object} couponInfo -优惠券信息 需要这三个字段 member_coupon_no,use_threshold,coupon_discount
 * @property {array} vipPriceList -会员价列表  srvretail_goods_member_select
 * @property {array} activityList - 营销活动列表 srvmkt_available_promotion_activity_select
 * @property {object} vipSetting - 会员优惠设置 srvretail_member_setup_select
 * @property {object} otherData - 计算无关参数 
 */
const calcBillResult = (cartList = [], vipInfo = {}, discountData = {
    type: "", // vip|discount|change|free|coupon 会员价、整单折扣、整单改价、免单、优惠券
    discountAmount: 0, // 整单减免金额/整单折扣比例（0-100）
    subtractPrice: 0, //抹零金额
    vipPayAmount: 0, //会员余额支付金额
    integralPayAmount: 0, //积分抵扣金额
  }, couponInfo = {
    member_coupon_no: "", // 会员优惠券编号
    use_threshold: "", // 使用门槛 无门槛|最低消费
    coupon_discount: 0 //优惠券减免金额
  }, vipPriceList = [],
  activityList = [], vipSetting = {}, otherData = {
    pay_type: "",
    discount_reason: "",
    discount_reason_name: "",
    remark: "",
    store_no: "",
    order_channel: "",
    sales_clerk: "",
    sales_clerk_staff: ""
  }) => {
  try {
    if (typeof cartList === 'string') {
      cartList = JSON.parse(cartList)
    }
    list = cartList
  } catch (e) {
    //TODO handle the exception
  }
  try {
    if (typeof vipInfo === 'string') {
      vipInfo = JSON.parse(vipInfo)
    }
    member_level_no = vipInfo?.member_level_no
    member_no = vipInfo?.member_no || vipInfo?.menber_no
  } catch (e) {
    //TODO handle the exception
  }
  try {
    if (typeof discountData === 'string') {
      discountData = JSON.parse(discountData)
    }
  } catch (e) {
    //TODO handle the exception
  }
  try {
    if (typeof couponInfo === 'string') {
      couponInfo = JSON.parse(couponInfo)
    }
  } catch (e) {
    //TODO handle the exception
  }
  try {
    if (typeof vipPriceList === 'string') {
      vipPriceList = JSON.parse(vipPriceList)
    }
  } catch (e) {
    //TODO handle the exception
  }
  try {
    if (typeof activityList === 'string') {
      activityList = JSON.parse(activityList)
    }
  } catch (e) {
    //TODO handle the exception
  }
  try {
    if (typeof vipSetting === 'string') {
      vipSetting = JSON.parse(vipSetting)
    }
  } catch (e) {
    //TODO handle the exception
  }
  try {
    if (typeof otherData === 'string') {
      otherData = JSON.parse(otherData)
    }
  } catch (e) {
    //TODO handle the exception
  }

  const {
    member_coupon_no, // 会员优惠券编号
    use_threshold, // 使用门槛 无门槛|最低消费
    discount_amount: coupon_discount //优惠券减免金额
  } = couponInfo || {}

  const cartGoodsNos = [...new Set(cartList.map(item => item.goods_no))]

  //组装活动列表
  const $activityList = buildActivityList(activityList, cartGoodsNos)

  let discountType = discountData.type; //优惠类型

  const {
    discountAmount, // 整单减免金额/整单折扣比例（0-100）
    subtractPrice, //抹零金额
    vipPayAmount, //会员余额支付金额
    integralPayAmount //积分抵扣金额
  } = discountData

  if (discountType === 'vip' && !member_level_no) {
    discountType = ''
  }

  const result = {
    order_total_amount: 0, // 订单总金额，不使用优惠的
    order_amount: 0, //订单金额 折扣、优惠、抹零过后的金额
    channel_source: "台式消费机", //订单来源

    discount_mode: '无', //  打折/优惠方式 enum('无','打折','减免')
    discount_type: '不优惠', // enum('不优惠','整单手动打折/改价','免单')

    change_price: 0, //整单改价金额

    member_discount: 0, //会员价优惠金额
    discount_reduction_amount: 0, //	折扣/减免金额
    free_discount_amount: 0, //免单优惠金额
    cash_reduction_amount: 0, //抹零金额

    discount_full_decrement: 0, // 促销-满额减现 折扣金额
    discount_direct: 0, //	促销-直接折扣 折扣金额

    integral_deduction: 0, //积分抵扣金额

    coupon_discount: 0, // 优惠券优惠--金额
    coupon_no: '', // 优惠券编号

    discount_amount: 0, // 总优惠金额

    order_detail: [], // 订单商品详情

    _activities: [], // 参加的所有营销活动,

    // 不参与计算的信息
    member_no, //会员编号
    totalAmountNotChangePrice: 0, //非改价商品价格合计
    _orderData: {}, //订单提交数据
  }
  let ignoreGoodsNos = []
  if (Array.isArray(cartList) && cartList.length > 0) {
    cartList.forEach(item => {
      const amount = item.amount || item.goods_num
      item.amount = amount
      result.order_total_amount += amount * item.sale_price
      item._cur_sale_price = item.sale_price
      if (item.goods_price && item.goods_price !== item.sale_price) {
        item._is_change_price = true
        ignoreGoodsNos.push(item.goods_no)
        return
      }

      //非改价商品价格合计 改价商品不参与优惠
      result.totalAmountNotChangePrice += amount * item.sale_price
    })
    // 非改价商品
    let newCartList = cartList.filter(item => item._is_change_price !== true)

    // 使用优惠券逻辑 取消会员价、促销活动；整单使用 优惠券 结算；
    const couponData = useCoupon(couponInfo, result.order_total_amount)
    if (couponData?.coupon_no) {
      result.coupon_no = couponData.coupon_no
      result.coupon_discount = couponData.coupon_discount
      result.discount_amount += result.coupon_discount
    }
  }

  return result
}

/**
 * @description 计算优惠券是否可用，优惠券可减免的金额
 * @property {object} couponInfo 优惠券信息
 * @property {number} total 订单非改价商品价格合计
 * @property {array} list 购物车列表
 */
const useCoupon = (couponInfo = {}, total = 0, list = []) => {
  const res = {
    coupon_discount: 0, //优惠券减的金额
    coupon_no: null,
  }
  if (Array.isArray(list) && list.length > 0) {
    const curTime = new Date().getTime()
    const startTime = new Date(couponInfo.available_start_time).getTime()
    const endTime = new Date(couponInfo.available_end_time).getTime()
    if (curTime < endTime && curTime > startTime) {
      // 在活动起止时间内
      const {
        use_threshold, //使用门槛
        min_consumption: min,
        coupon_type: type, //优惠券类型
        discount_amount: amount, // 优惠券面额
        member_coupon_no: no, //优惠券编号
      } = couponInfo
      if (use_threshold === '无门槛' || (use_threshold === "最低消费" && total >=
          min)) {
        
        list.forEach(item => {
          let coupon_discount = 0
          const sumPrice = item.sale_price * item.amount
          if (type === "折扣券") {
            const rate = couponInfo.discount_num /10 //打折比例
            coupon_discount = toFixed2((rate-1)*sumPrice)
          } else {
            let rate = sumPrice/total
            coupon_discount = rate*amount
            coupon_discount = coupon_discount > sumPrice ? -sumPrice : -coupon_discount
          }
          item._cur_sale_price = item.sale_price + coupon_discount
          if (item._cur_sale_price > item.minimum_price) {
            // 当前售价小于最低售价
            if (item.allow_min_sales_price === '不允许') {
              coupon_discount += item.sale_price - item.minimum_price
              item._cur_sale_price = item.minimum_price
            }
          }
          item._coupon_discount = coupon_discount
          res.discount_amount += coupon_discount
        })
        res.coupon_no = couponInfo.no
      }
    }
  }
  return res
}

/**
 * 用活动商品列表组成活动列表
 * @property {Array} list       - 活动商品列表
 * @property {Array} goods_nos  - 购物车商品列表
 */
const buildActivityList = (list = [], goods_nos = []) => {
  if (!goods_nos || goods_nos.length === 0) {
    // 没有符合活动的商品
    return []
  }
  return list.reduce((pre, cur) => {
    if (goods_nos && goods_nos.includes(cur.goods_no)) {
      if (cur?.participants === '指定会员等级') {
        // 过滤掉不符合会员等级的活动
        if (!member_level_no || cur.member_level_name && member_level_no && cur.member_level_name.indexOf(
            member_level_no) === -1) {
          return pre
        }
      }
      if (cur?.weekly_take_effect) {
        // 过滤掉不在设置的活动日（周几）的活动
        let weekly = new Date().getDay() // 0-6
        let weekMap = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
        if (cur.weekly_take_effect.indexOf(weekMap[weekly]) === -1) {
          return pre
        }
      }
      const activityIndex = pre.findIndex(item => item.promotion_no === cur.promotion_no)
      if (activityIndex > -1) {
        // 已有同一个活动
        pre[activityIndex]._goods_nos.push(cur.goods_no)
      } else {
        cur._goods_nos = [cur.goods_no]
        pre.push(cur)
      }
    }
  }, [])
}


const toFixed2 = (num) => {
  return !isNaN(Number(num)) ? Number(Number(num).toFixed(2)) : 0
}
